feat(validator): add unique validator constraint#179
Conversation
# Conflicts: # src/validator/constraints/index.ts
* feat: add passing type constraint * chore: cover type constraint violation * chore: support matching type constraint values * chore: support type constraint alternatives * chore: allow optional type constraint values * chore: support type constraint custom message * chore: format type constraint alternatives * chore: register type constraint # Conflicts: # src/validator/constraints/index.ts * chore: fix code style * chore: use TypeOptions due to rebase * Simplify type constraint message formatting * chore: add separate test case for the undefined values. * chore: refactor getDefaultMessageWith method. * chore: add a list of AllowedTypes types * chore: code format * chore: remove redundant test case * chore: remove redundant check * chore: fix AllowedTypes * chore: inline options * chore: rename test case * chore: use one default message * chore: inline method * chore: rename AllowedType * chore: refactor normalizedTypes * chore: remove the undefined type case from each * chore(validator): make constraint options generic * chore: align type constraint options * chore: code refactoring * chore: fix type mismatch --------- Co-authored-by: Dhemy <imdhemy@gmail.com>
# Conflicts: # src/validator/constraints/index.ts
66fbc49 to
0cc1b39
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new built-in unique validation constraint under the validator’s comparison constraints, enabling uniqueness checks for array values (optionally via normalization and/or a field-combination key for arrays of objects).
Changes:
- Added
uniqueconstraint implementation withmessage,normalizer, andfieldsoptions. - Added Vitest coverage for core
uniquebehaviors. - Registered and exported
unique(andUniqueOptions) via the constraints public API.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/validator/constraints/index.ts |
Registers unique in builtInConstraints and exports it from the constraints module. |
src/validator/constraints/comparison/unique.ts |
Implements the unique constraint with optional normalization and field-based uniqueness checks. |
src/validator/constraints/comparison/unique.test.ts |
Adds tests for uniqueness, custom messages, normalization, and field-combination checks. |
imdhemy
left a comment
There was a problem hiding this comment.
@EmanFateen Thank you!
I’ve made some improvements to the tests and adjusted the source code to align with the intended behavior. Here’s a summary of the changes:
-
Changed
uniqueto compare array elements by value, not reference:- nested arrays with the same values now fail validation.
- objects with the same values now fail validation.
- different array/object values still pass.
-
Fixed normalizer semantics:
normalizernow always runs on each array element first.- configured
fieldsare read from normalized elements. - normalizer no longer runs on individual field values.
-
Added missing value-shape coverage in
unique.test.ts:- arrays of scalars
- arrays of arrays
- arrays of objects
- object field combinations
-
Added explicit
nullandundefinedbehavior:- whole-value
undefinedpasses by bypass. - whole-value
nullfails as non-array. [null]and[undefined]pass.[null, null]and[undefined, undefined]fail.
- whole-value
-
Split failure messages by failure reason:
- non-array values use
This value should be an array. - duplicate values use
This array should contain only unique elements.
- non-array values use
-
Aligned wording from
collectiontoarray. -
Regrouped the test suite:
non-array valuesarrays of scalarsarrays of arraysarrays of objectsoptions
-
Switched test declarations from
it(...)totest(...). -
Reworded test names to standalone phrases such as:
validation passes when ...validation fails when ...validation normalizes ...
Overview
In this PR, I have introduced a new validation constraint called
unique.It's exposed through the builtInConstraints and can be used like
Changes made: